<?php

/**
 * WeEngine System
 *
 * (c) We7Team 2021 <https://www.w7.cc>
 *
 * This is not a free software
 * Using it under the license terms
 * visited https://www.w7.cc for more details
 */

namespace App\Http\Logic;

use App\Exceptions\LogicErrorException;
use App\Models\PayLog;
use GuzzleHttp\Client;

class PayLogic
{
    public static function getSignForContent(array $params): string
    {
        unset($params['sign']);
        $params = self::toString($params);

        ksort($params);

        $stringToBeSigned = '';
        $i                = 0;

        foreach ($params as $k => $v) {
            if (!empty($v)) {
                if (!is_scalar($v)) {
                    $v = json_encode($v);
                }

                if (0 == $i) {
                    $stringToBeSigned .= "$k" . '=' . "$v";
                } else {
                    $stringToBeSigned .= '&' . "$k" . '=' . "$v";
                }
                $i++;
            }
        }

        return md5(md5($stringToBeSigned) . env('SITE_AUTH_KEY'));
    }

    protected static function toString($param): array|string
    {
        if (empty($param)) {
            return '';
        }

        if (is_array($param)) {
            return array_map(function ($value) {
                return self::toString($value);
            }, $param);
        }

        return (string)$param;
    }

    public static function create(array $data)
    {
        $result = self::rpc($data);

        if (!isset($data['amount'])) {
            $data['amount'] = $data['total'] / 100;
        }

        PayLog::query()->create($data);

        return $result;
    }

    public static function rpc(array &$data)
    {
        $account_id = \AppData::getAccountId();
        if (empty($account_id)) {
            throw new LogicErrorException('请从号码中进入');
        }

        $data['account_id'] = $account_id;

        $data['sign'] = PayLogic::getSignForContent($data);
        $client       = new Client();
        $result       = $client->post(url('pay/create'), [
            'form_params' => $data
        ]);

        return $result->getBody();
    }

    public static function refund(string $pay_type, string $out_trade_no)
    {
        $log = PayLog::query()
            ->where('out_trade_no', $out_trade_no)
            ->where('pay_type', $pay_type)
            ->first(['amount', 'status', 'id']);

        if (empty($log)) {
            throw new LogicErrorException('指定订单不存在');
        }

        if (0 == $log->status) {
            throw new LogicErrorException('指定订单未支付');
        }

        if (2 == $log->status) {
            throw new LogicErrorException('指定订单已退款');
        }

        return $log;
    }
}
